package top.infopub.tdp.sys.service.impl;


import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import top.infopub.exception.CodeGeneratorException;
import top.infopub.generic.GenericDao;
import top.infopub.generic.GenericServiceImpl;
import top.infopub.model.sys.CodeGeneratorConfig;
import top.infopub.tdp.sys.dao.CodeGeneratorConfigDao;
import top.infopub.tdp.sys.service.CodeGeneratorConfigService;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;


@Service
public class CodeGeneratorConfigServiceImpl extends GenericServiceImpl<CodeGeneratorConfig, Long> implements CodeGeneratorConfigService {

    private static Logger LOGGER = LoggerFactory.getLogger(CodeGeneratorConfigServiceImpl.class);

    @Autowired
    private CodeGeneratorConfigDao codeGeneratorConfigDao;

    @Override
    public GenericDao<CodeGeneratorConfig, Long> getDao() {
        return codeGeneratorConfigDao;
    }

    // 事务独立 
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public String generatorCode(String codeType) {
        if (StringUtils.isEmpty(codeType)) {
            throw new CodeGeneratorException("generatorCode,codetype is null");
        }
        // 这里直接使用了数据库锁 保证UK
        CodeGeneratorConfig currCodeResult = codeGeneratorConfigDao.selectCodeGenerConfigByTypeAndLock(codeType);
        if (currCodeResult == null || currCodeResult.getCodeStart() == null) {
            throw new CodeGeneratorException("generatorCode,codetype :" + codeType
                                             + " , config info is null or error");
        }
        if (currCodeResult.getCodeStep() == null) {
            currCodeResult.setCodeStep(20);
        }
        try {
            if (StringUtils.isNotEmpty(currCodeResult.getCodeDateformat())) {
                String lastCodeValue = currCodeResult.getLastCodeValue();
                String currentDate = getCurrentDate(currCodeResult.getCodeDateformat());
                if ((StringUtils.isNotEmpty(currentDate))
                    && (!(lastCodeValue == null ? "" : lastCodeValue).contains(currentDate))) {
                    // 每日从1开始
                    currCodeResult.setCodeStart(1);
                }
            }
            String returnValue = generatorCode(currCodeResult, currCodeResult.getCodeStart()
                                                                 + currCodeResult.getCodeStep()
                                                                 - 1);
            // generatorCode
            currCodeResult.setLastCodeValue(returnValue);
            currCodeResult.setCodeStart(currCodeResult.getCodeStart()
                                        + currCodeResult.getCodeStep());
            this.updateBySelective(currCodeResult);
            return returnValue;
        }
        catch (Exception e) {
            LOGGER.error("", e);
            return null;
        }
    }

    private String generatorCode(CodeGeneratorConfig currCodeResult, int size) {
        StringBuilder _stb = new StringBuilder(
            StringUtils.isEmpty(currCodeResult.getCodePrefix()) ? "" : currCodeResult.getCodePrefix());
        if (currCodeResult.getCodeDateformat() != null) {
            _stb.append(getCurrentDate(currCodeResult.getCodeDateformat()));
        }
        String _i = size + "";
        // leftPad
        int differ = currCodeResult.getCodeSize() - _i.length();
        if (differ >= 1) {
            for (int d = 0; d < differ; d++ ) {
                _stb.append("0");
            }
        }
        _stb.append(_i);
        return _stb.toString();
    }

    private String getCurrentDate(String format) {
        try {
            return new SimpleDateFormat(format).format(new Date());
        }
        catch (Exception e) {
            return "";
        }
    }

    @Override
    public void batchUpdateDelFlag(String[] ids, String flag) {
        codeGeneratorConfigDao.batchUpdateDelFlag(ids, flag);
    }

    @Override
    public Page<CodeGeneratorConfig> selectByCode(Page<CodeGeneratorConfig> page,
                                                  CodeGeneratorConfig codeGeneratorConfig) {
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        return (Page<CodeGeneratorConfig>)codeGeneratorConfigDao.selectByCode(codeGeneratorConfig);
    }

    @Override
    public int proCodeIsTrue(String proCode) {
        return codeGeneratorConfigDao.proCodeIsTrue(proCode);
    }

}